#!/usr/bin/env python
# encoding: utf-8


"""
@file: zhixian_quyu_jiaodian.py
@time: 2017/4/24 上午10:22
"""
# 直线与区域交点问题
from mathsolver.functions.root.jiefangchenzu import *
from mathsolver.functions.budengshi import common_opers as co
from operator import itemgetter


# 直线与区域交点个数问题
# style1:  Input: paramer1:eq(直线); Input2:ineqs(不等式组表示的区域)  Output: 输出交点的个点
class ZhiXianYuQuYuJiaoDian(BaseFunction):
    """
    直线2x+y-10=0与不等式组\\{\\begin{array}{c}x≥0,\\\\y≥0,\\\\x-y≥-2,\\\\4x+3y≤20\\end{array}表示的平面区域的公共点有()
    """
    def solver(self, *args):
        self.label.add('直线与可行域交点个数')
        l1, r1 = args[0].sympify()
        f1 = l1 - r1  # 直线表示的表达式
        inter_points = co.satisfied_ineqs_intersections(args[1])  # 满足条件的交点
        inter_points = map(itemgetter(1), inter_points)
        point_values = map(lambda _: (_[0][1], _[1][1]), inter_points)
        step1 = ''
        for i, p in enumerate(point_values):
            if i == 0:
                step1 += '(' + new_latex(p[0]) + ',' + new_latex(p[1]) + ')'
            else:
                step1 += ' ' + '(' + new_latex(p[0]) + ',' + new_latex(p[1]) + ')'
        self.steps.append(['由题意可知求得满足条件的交点:', step1])
        f1_vs = list(map(lambda _: f1.subs(_), inter_points))
        self.steps.append(['交点带入直线 ' + args[0].printing(), '得:'])
        step2 = ''
        for i, v in enumerate(f1_vs):
            if i == 0:
                step2 += new_latex(v)
        size1 = len(f1_vs)
        c1 = list(filter(lambda _: _ > 0, f1_vs))  # 所有大于0的情况
        c1_size = len(c1)
        c2 = list(filter(lambda _: _ < 0, f1_vs))  # 所有小于0的情况
        c2_size = len(c2)
        c3 = list(filter(lambda _: _ == 0, f1_vs))  # 等于0的情况
        c3_size = len(c3)
        count = -1
        if c1_size == size1 or c2_size == size1:  # 1 如果所有值均大于0或者均小于0 则直线与区域无公共点
            count = 0
            self.steps.append(['由图像可知直线' + args[0].printing(), '与区域有0个交点'])
        elif c1_size >= 1 and c2_size >= 1:  # 2 若存在两个值异号，则直线与区域有无数公共点
            count = S.Infinity
            self.steps.append(['由图像可知直线' + args[0].printing(), '与区域有无数个交点'])
        elif c3_size == 1 and c1_size * c2_size == 0:  # 3 若存在一个值为0，其他值均大于0 或小于0 则直线过该顶点，与区域只有一个公共点
            count = 1
            self.steps.append(['由图像可知直线' + args[0].printing(), '与区域有1个交点'])
        elif c3_size == 2 and c1_size * c2_size == 0:  # 4 若存在两个值为0，其他值均大于0或小于0 则直线过该顶点的边界，与区域有无数多公共点
            count = S.Infinity
            self.steps.append(['由图像可知直线' + args[0].printing(), '与区域有无数个交点'])
        self.output.append(BaseNumber(count))
        return self


if __name__ == '__main__':
    s1 = ZhiXianYuQuYuJiaoDian(verbose=True).solver(BaseEq(['2*x + y - 10', '0']), BaseIneqs(
        [['x', '>=', '0'], ['y', '>=', '0'], ['x - y', '>=', '-2'], ['4*x + 3*y', '<=', '20']]))
